# -*- coding: utf-8 -*-
#
# Copyright (c) 2017 - 2018, doudoudzj
# All rights reserved.
#
# Intranet is distributed under the terms of the New BSD License.
# The full license can be found in 'LICENSE'.

"""Package for reading and writing Apache configuration.
"""

import glob
import os
import re
import shutil
import sys
from cStringIO import StringIO

# import utils

DEBUG = False


# HTTPD_CONF_DIR = '/etc/httpd/'
HTTPD_CONF_DIR = '/Users/douzhenjiang/Projects/intranet-panel/'
HTTPD_CONF = '/etc/httpd/conf/httpd.conf'
SERVER_CONF = '/etc/httpd/conf.d/'
COMMENTFLAG = '#v#'
GENBY = 'Generated by Intranet'

ABC = '/etc/httpd/conf.d/abc.com.conf'

vHostTemplate = '''<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www
    <Directory />
        Options FollowSymLinks
        AllowOverride None
    </Directory>
    <Directory /var/www/>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride None
        Order allow,deny
        allow from all
    </Directory>
</VirtualHost>
'''


DIRECTIVES = {
    'Directory': '',
    'Files': '',
    'Limit': '',
    'Location': '',
    'VirtualHost': ''
}

OPTIONS = {
    'DocumentRoot': '',
    'ServerAdmin': '',
    'Limit': '',
    'Location': '',
    'VirtualHost': ''
}

DEFAULTVALS = {
    'VirtualHost': '*:80',
    'Directory': '',
}


def virtual_host_config(site, key, val, port=80):
    '''
    site: abc.com
    key: VirtualHost or DocumentRoot or ServerAdmin or Directory
    val: /var/www
    '''
    keys = ['VirtualHost', 'DocumentRoot', 'ServerAdmin', 'Directory']
    if key not in keys or not site or not val:
        return False

    conf = SERVER_CONF + site + '.conf'
    try:
        os.stat(conf)
    except OSError:
        print('site config file not exist')
        return False

    old_conf = open(conf).read()

    with open(conf + '.bak', 'w') as f:
        # backup
        f.write(old_conf)

    if key == 'VirtualHost':
        conf = SERVER_CONF + val + '.conf'
        val = str(val) + ':' + str(port)
        # os.renames(SERVER_CONF + site + '.conf', conf + '.bak')

    # make new config
    new_conf = re.sub(key + ' "(.*?)"',
                      key + ' "' + val + '"',
                      old_conf)

    # save new config file
    with open(conf, 'w') as f:
        f.write(new_conf)
        # delete old site config file
        if key == 'VirtualHost' and os.stat(conf) and os.stat(SERVER_CONF + site + '.conf.bak'):
            os.remove(SERVER_CONF + site + '.conf')
        return True


# https://blog.csdn.net/brucemj/article/details/37933519
# https://oomake.com/question/266681


def replace_docroot(vhost, new_docroot):
    '''yield new lines of an httpd.conf file where docroot lines matching
        the specified vhost are replaced with the new_docroot
    '''
    vhost_start = re.compile(r'<VirtualHost\s+(.*?)>')
    vhost_end = re.compile(r'</VirtualHost>')
    docroot_re = re.compile(r'(DocumentRoot\s+)(\S+)')
    file = open(HTTPD_CONF_DIR + vhost + '.conf').read()
    conf_file = StringIO(file)
    in_vhost = False
    curr_vhost = None
    for line in conf_file:
        # 起始行查找host
        vhost_start_match = vhost_start.search(line)
        if vhost_start_match:
            curr_vhost = vhost_start_match.groups()[0]
            in_vhost = True
            print(curr_vhost, vhost)
        if in_vhost and (curr_vhost == vhost):
            docroot_match = docroot_re.search(line)
            if docroot_match:
                sub_line = docroot_re.sub(r'\1%s' % new_docroot, line)
                line = sub_line
            vhost_end_match = vhost_end.search(line)
            if vhost_end_match:
                in_vhost = False
            yield line


def addserver(server_names):
    servercfg = ['# %s' % GENBY]
    configfile = os.path.join(HTTPD_CONF_DIR, '%s.conf' % server_names)
    configfile_exists = os.path.exists(configfile)

    # check if need to add a new line at the end of the file to
    # avoid first line go to the same former } line
    if configfile_exists:
        with open(configfile) as f:
            f.seek(-1, 2)
            if f.read(1) != '\n':
                servercfg.insert(0, '')
    with open(configfile, configfile_exists and 'a' or 'w') as f:
        f.write('\n'.join(servercfg))
    return True


def loadconfig(conf=None, getlineinfo=False):
    """Load apache config and return a dict.
    """
    if not conf:
        conf = HTTPD_CONF
    if not os.path.exists(conf):
        return False
    return _loadconfig(conf, getlineinfo)


def getservers(config=None):
    '''Get servers from apache configuration files.
    '''
    servers = [{
        "server_names": [
            "_"
        ],
        "status": "on",
        "engines": [
            "static"
        ],
        "listens": [
            {
                "ip": "*",
                "port": "80",
                "default_server": True
            },
            {
                "ip": "[",
                "port": ":]:80",
                "default_server": True
            }
        ]
    },
        {
        "server_names": [
            "api.intranet.pub"
        ],
        "status": "on",
        "engines": [
            "static"
        ],
        "listens": [
            {
                "ip": "*",
                "port": "80",
                "default_server": False
            }
        ]
    },
        {
        "server_names": [
            "web.intranet.pub"
        ],
        "status": "on",
        "engines": [
            "static",
            "fastcgi"
        ],
        "listens": [
            {
                "ip": "*",
                "port": "80",
                "default_server": False
            }
        ]
    }]
    return servers


def _context_getservers(disabled=None, config=None, getlineinfo=True):
    """Get server context configs.
    """
    if not config or config['_isdirty']:
        config = loadconfig(HTTPD_CONF, getlineinfo)
    http = config['_'][0]['http'][0]
    if not http.has_key('server'):
        return []
    servers = http['server']
    if disabled == None or not getlineinfo:
        return servers
    else:
        return [server for server in servers
                if server['_param']['disabled'] == disabled]


if __name__ == '__main__':
    # virtual_host_config('aaa.com', 'DocumentRoot', '/v/asfs34535')
    # virtual_host_config('aaa.com', 'ServerAdmin', '4567896543')
    # virtual_host_config('aaa.com', 'VirtualHost', 'bbb.com', 567)

    # 输出
    # for line in replace_docroot('aaa.com', 'docroot'):
    #     print(line)

    # addserver('aaaaaa.com')

    from apacheconfig import *

    with make_loader() as loader:
        config = loader.load(HTTPD_CONF_DIR + 'aaa.com.conf')

        print(config)
        # print(loader.dumps(config))
